﻿//-------------------------------------------------------------------
//	Copyright (c) 2010-2014  Zhirnov Andrey
//	This file is part of the "UX Standard Lib" project.
//	See copyright notice in "UX_STL_Ext.h".
//-------------------------------------------------------------------

#ifndef _UXS_GL_ENUMS_H
#define _UXS_GL_ENUMS_H

#pragma once

#include "../opengl.h"

namespace UX_STL
{
namespace GLShell
{
	using namespace UXMath;

	typedef uint16		GLenum_t;


// ------------------------- GL Object Type ---------------------- //

namespace gl_object
{
	enum	type	: GLenum_t
	{
		UNKNOWN			= 0,
		BUFFER,				// VBO, IBO, ...
		VERTEX_ARRAY,		// = GL_VERTEX_ARRAY_BINDING
		QUERY,				// = GL_QUERY_BINDING
		SAMPLER,			// = GL_SAMPLER_BINDING
		SHADER,				// = GL_SHADER_TYPE
		PROGRAM,			// GL_CURRENT_PROGRAM
		PROGRAM_PIPELINE,	// = GL_PROGRAM_PIPELINE_BINDING
		TEXTURE				= GL_TEXTURE,
		FRAMEBUFFER			= GL_FRAMEBUFFER,
		RENDERBUFFER		= GL_RENDERBUFFER,
		TRANSFORM_FEEDBACK	= GL_TRANSFORM_FEEDBACK,
		SYNC				= GL_SYNC_CL_EVENT_ARB,
	};
}


// ------------------------ Buffer Targets ----------------------- //

namespace gl_buffer
{
	enum	type	: GLenum_t
	{
		ARRAY				= GL_ARRAY_BUFFER,
		ATOMIC_COUNTER		= GL_ATOMIC_COUNTER_BUFFER,
		COPY_READ			= GL_COPY_READ_BUFFER,
		COPY_WRITE			= GL_COPY_WRITE_BUFFER,
		DRAW_INDIRECT		= GL_DRAW_INDIRECT_BUFFER,
		ELEMENT_ARRAY		= GL_ELEMENT_ARRAY_BUFFER,
		PIXEL_PACK			= GL_PIXEL_PACK_BUFFER,
		PIXEL_UNPACK		= GL_PIXEL_UNPACK_BUFFER,
		TEXTURE				= GL_TEXTURE_BUFFER,
		TRANSFORM_FEEDBACK	= GL_TRANSFORM_FEEDBACK_BUFFER,
		UNIFORM				= GL_UNIFORM_BUFFER,
		SHADER_STORAGE		= GL_SHADER_STORAGE_BUFFER,

		// renamed
		INDEX				= ELEMENT_ARRAY,
		VERTEX				= ARRAY,
		_INIT				= VERTEX,
		_UNKNOWN			= 0,
	};
}


// ------------------------- Query Targets ----------------------- //

namespace gl_query
{
	enum	type	: GLenum_t
	{
		SAMPLES_PASSED							= GL_SAMPLES_PASSED,
		ANY_SAMPLES_PASSED						= GL_ANY_SAMPLES_PASSED,
		TIME_ELAPSED							= GL_TIME_ELAPSED,
		TIMESTAMP								= GL_TIMESTAMP,
		PRIMITIVES_GENERATED					= GL_PRIMITIVES_GENERATED,
		TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN	= GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN,
		ANY_SAMPLES_PASSED_CONSERVATIVE			= GL_ANY_SAMPLES_PASSED_CONSERVATIVE,
		_INIT									= 0,
	};
}


// ---------------------- Conditional Render Mode ---------------- //

namespace gl_cond_render
{
	enum	type	: GLenum_t
	{
		QUERY_WAIT					= GL_QUERY_WAIT,
		QUERY_NO_WAIT				= GL_QUERY_NO_WAIT,
		QUERY_BY_REGION_WAIT		= GL_QUERY_BY_REGION_WAIT,
		QUERY_BY_REGION_NO_WAIT		= GL_QUERY_BY_REGION_NO_WAIT,
		_INIT						= 0,
	};
}


// ------------------------ Cube Map Face ------------------------ //

namespace gl_cube_face
{
	enum	type	: GLenum_t
	{
		POSITIVE_X	= GL_TEXTURE_CUBE_MAP_POSITIVE_X,
		NEGATIVE_X	= GL_TEXTURE_CUBE_MAP_NEGATIVE_X,
		POSITIVE_Y	= GL_TEXTURE_CUBE_MAP_POSITIVE_Y,
		NEGATIVE_Y	= GL_TEXTURE_CUBE_MAP_NEGATIVE_Y,
		POSITIVE_Z	= GL_TEXTURE_CUBE_MAP_POSITIVE_Z,
		NEGATIVE_Z	= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z,
		_FIRST		= POSITIVE_X,
		_LAST		= NEGATIVE_Z,
		_INIT		= _FIRST,
		_UNKNOWN	= 0,
	};

	UX_ENUM_ADD_OPERATIONS( type )
}


// ------------------------ Texture Targets ---------------------- //

namespace gl_texture
{
	enum	type	: GLenum_t
	{
		TEXTURE_1D						= GL_TEXTURE_1D,
		TEXTURE_2D						= GL_TEXTURE_2D,
		TEXTURE_3D						= GL_TEXTURE_3D,
		TEXTURE_CUBE_MAP				= GL_TEXTURE_CUBE_MAP,
		TEXTURE_1D_ARRAY				= GL_TEXTURE_1D_ARRAY,
		TEXTURE_2D_ARRAY				= GL_TEXTURE_2D_ARRAY,
		TEXTURE_2D_MULTISAMPLE			= GL_TEXTURE_2D_MULTISAMPLE,
		TEXTURE_2D_MULTISAMPLE_ARRAY	= GL_TEXTURE_2D_MULTISAMPLE_ARRAY,
		TEXTURE_CUBE_MAP_ARRAY			= GL_TEXTURE_CUBE_MAP_ARRAY,
		TEXTURE_BUFFER					= GL_TEXTURE_BUFFER,
		TEXTURE_RECTANGLE				= GL_TEXTURE_RECTANGLE,
		TEXTURE_VIEW					= GL_TEXTURE_VIEW,
		_INIT							= TEXTURE_2D,
		_UNKNOWN						= 0,
		
		// rename //
		TEXTURE_2DMS					= TEXTURE_2D_MULTISAMPLE,
		TEXTURE_2DMS_ARRAY				= TEXTURE_2D_MULTISAMPLE_ARRAY,

		// for creating CLimage //
		_CUBEFACE_POSITIVE_X			= GL_TEXTURE_CUBE_MAP_POSITIVE_X,
		_CUBEFACE_NEGATIVE_X			= GL_TEXTURE_CUBE_MAP_NEGATIVE_X,
		_CUBEFACE_POSITIVE_Y			= GL_TEXTURE_CUBE_MAP_POSITIVE_Y,
		_CUBEFACE_NEGATIVE_Y			= GL_TEXTURE_CUBE_MAP_NEGATIVE_Y,
		_CUBEFACE_POSITIVE_Z			= GL_TEXTURE_CUBE_MAP_POSITIVE_Z,
		_CUBEFACE_NEGATIVE_Z			= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z,
		_CUBEFACE_FIRST					= _CUBEFACE_POSITIVE_X,
		_CUBEFACE_LAST					= _CUBEFACE_NEGATIVE_Z,

		// for render target
		_RENDER_BUFFER					= GL_RENDERBUFFER,
	};

	inline gl_cube_face::type ToCubeFace(type t)
	{
		ASSERT( t >= _CUBEFACE_FIRST and t <= _CUBEFACE_LAST );
		return (gl_cube_face::type)t;
	}

	UX_ENUM_ADD_OPERATIONS( type )
}


// ------------------------ Draw Buffer -------------------------- //

namespace gl_draw_buffer
{
	enum	type	: GLenum_t
	{
		NONE				= GL_NONE,
		FRONT_LEFT			= GL_FRONT_LEFT,
		FRONT_RIGHT			= GL_FRONT_RIGHT,
		BACK_LEFT			= GL_BACK_LEFT,
		BACK_RIGHT			= GL_BACK_RIGHT,
		FRONT				= GL_FRONT,
		BACK				= GL_BACK,
		LEFT				= GL_LEFT,
		RIGHT				= GL_RIGHT,
		FRONT_AND_BACK		= GL_FRONT_AND_BACK,
		_INIT				= NONE,
		_UNKNOWN			= type(-1),
	};
}


// ----------------------- System Buffer ------------------------- //

namespace gl_system_buffer
{
	enum	type	: GLenum_t
	{
		NONE				= GL_NONE,
		FRONT_LEFT			= GL_FRONT_LEFT,
		FRONT_RIGHT			= GL_FRONT_RIGHT,
		BACK_LEFT			= GL_BACK_LEFT,
		BACK_RIGHT			= GL_BACK_RIGHT,
		DEPTH				= GL_DEPTH,
		STENCIL				= GL_STENCIL,
	};
}


// ------------------------ Read Buffer -------------------------- //

namespace gl_read_buffer
{
	enum	type	: GLenum_t
	{
		NONE				= GL_NONE,
		FRONT_LEFT			= GL_FRONT_LEFT,
		FRONT_RIGHT			= GL_FRONT_RIGHT,
		BACK_LEFT			= GL_BACK_LEFT,
		BACK_RIGHT			= GL_BACK_RIGHT,
		FRONT				= GL_FRONT,
		BACK				= GL_BACK,
		LEFT				= GL_LEFT,
		RIGHT				= GL_RIGHT,
		FRONT_AND_BACK		= GL_FRONT_AND_BACK,
		COLOR_0				= GL_COLOR_ATTACHMENT0,
		COLOR_1				= GL_COLOR_ATTACHMENT1,
		COLOR_2				= GL_COLOR_ATTACHMENT2,
		COLOR_3				= GL_COLOR_ATTACHMENT3,
		COLOR_4				= GL_COLOR_ATTACHMENT4,
		COLOR_5				= GL_COLOR_ATTACHMENT5,
		COLOR_6				= GL_COLOR_ATTACHMENT6,
		COLOR_7				= GL_COLOR_ATTACHMENT7,
		COLOR_8				= GL_COLOR_ATTACHMENT8,
		COLOR_9				= GL_COLOR_ATTACHMENT9,
		COLOR_10			= GL_COLOR_ATTACHMENT10,
		COLOR_11			= GL_COLOR_ATTACHMENT11,
		COLOR_12			= GL_COLOR_ATTACHMENT12,
		COLOR_13			= GL_COLOR_ATTACHMENT13,
		COLOR_14			= GL_COLOR_ATTACHMENT14,
		COLOR_15			= GL_COLOR_ATTACHMENT15,
	};
}


// --------------------- Framebuffer Targets --------------------- //

namespace gl_fbo_target
{
	enum	type	: GLenum_t
	{
		FRAMEBUFFER			= GL_FRAMEBUFFER,
		DRAW_FRAMEBUFFER	= GL_DRAW_FRAMEBUFFER,
		READ_FRAMEBUFFER	= GL_READ_FRAMEBUFFER,
		_INIT				= FRAMEBUFFER,
		_UNKNOWN			= 0,
	};
}


// ---------------------- Framebuffer Objects -------------------- //

namespace gl_fbo_object
{
	enum	type :	GLenum_t
	{
		NONE			= GL_NONE,
		DEFAULT_FB		= GL_FRAMEBUFFER_DEFAULT,
		TEXTURE			= GL_TEXTURE,
		RENDERBUFFER	= GL_RENDERBUFFER,
	};
}


// --------------------- Framebuffer Blit Type ------------------- //

namespace gl_fbo_blit
{
	enum	type :	GLenum_t
	{
		NEAREST					= GL_NEAREST,
		LINEAR					= GL_LINEAR,
		SCALED_RESOLVE_FASTEST	= GL_SCALED_RESOLVE_FASTEST_EXT,
		SCALED_RESOLVE_NICEST	= GL_SCALED_RESOLVE_NICEST_EXT,
	};
}


// ------------------------ Primitive Types ---------------------- //

namespace gl_primitive
{
	enum	type	: GLenum_t
	{
		POINT						= GL_POINTS,
		LINE						= GL_LINES,
		LINE_LOOP					= GL_LINE_LOOP,
		LINE_STRIP					= GL_LINE_STRIP,
		TRIANGLE					= GL_TRIANGLES,
		TRIANGLE_STRIP				= GL_TRIANGLE_STRIP,
		TRIANGLE_FAN				= GL_TRIANGLE_FAN,
		LINE_STRIP_ADJACENCY		= GL_LINE_STRIP_ADJACENCY,
		LINE_ADJACENCY				= GL_LINES_ADJACENCY,
		TRIANGLE_STRIP_ADJACENCY	= GL_TRIANGLE_STRIP_ADJACENCY,
		TRIANGLE_ADJACENCY			= GL_TRIANGLES_ADJACENCY,
		//QUADS						= GL_QUADS,
		//QUAD_STRIP				= GL_QUAD_STRIP,
		//POLYGON					= GL_POLYGON,
		PATCH						= GL_PATCHES,
		_INIT						= TRIANGLE,
		_UNKNOWN					= 0,
	};
}


// ------------------------ Blend Equation ----------------------- //

namespace gl_blend_equation
{
	enum	type	: GLenum_t
	{
		ADD					= GL_FUNC_ADD,				// S+D
		SUB					= GL_FUNC_SUBTRACT,			// S-D
		REV_SUB				= GL_FUNC_REVERSE_SUBTRACT,	// D-S
		MIN					= GL_MIN,					// min(S,D)
		MAX					= GL_MAX,					// max(S,D)
		_INIT				= ADD,
		_UNKNOWN			= 0,
	};
}


// ------------------------- Blend Func -------------------------- //

namespace gl_blend_func
{
	enum	type	: GLenum_t
	{
		ZERO						= GL_ZERO,						// 0
		ONE							= GL_ONE,						// 1
		SRC_COLOR					= GL_SRC_COLOR,					// src
		ONE_MINUS_SRC_COLOR			= GL_ONE_MINUS_SRC_COLOR,		// 1 - src
		DST_COLOR					= GL_DST_COLOR,					// dst
		ONE_MINUS_DST_COLOR			= GL_ONE_MINUS_DST_COLOR,		// 1 - dst
		SRC_ALPHA					= GL_SRC_ALPHA,					// src.a
		ONE_MINUS_SRC_ALPHA			= GL_ONE_MINUS_SRC_ALPHA,		// 1 - src.a
		DST_ALPHA					= GL_DST_ALPHA,					// dst.a
		ONE_MINUS_DST_ALPHA			= GL_ONE_MINUS_DST_ALPHA,		// 1 - dst.a
		CONST_COLOR					= GL_CONSTANT_COLOR,			// cc
		ONE_MINUS_CONST_COLOR		= GL_ONE_MINUS_CONSTANT_COLOR,	// 1 - cc
		CONST_ALPHA					= GL_CONSTANT_ALPHA,			// cc.a
		ONE_MINUS_CONST_ALPHA		= GL_ONE_MINUS_CONSTANT_ALPHA,	// 1 - cc.a
		SRC_ALPHA_SATURATE			= GL_SRC_ALPHA_SATURATE,		// rgb * min( src.a, dst.a ), a * 1
		SRC1_COLOR					= GL_SRC1_COLOR,				// src1
		SRC1_ALPHA					= GL_SRC1_ALPHA,				// src1.a
		ONE_MINUS_SRC1_COLOR		= GL_ONE_MINUS_SRC1_COLOR,		// 1 - src1
		ONE_MINUS_SRC1_ALPHA		= GL_ONE_MINUS_SRC1_ALPHA,		// 1 - src1.a
		_INIT						= ZERO,
		_UNKNOWN					= type(-1),
	};
}


// ------------------------ Compare Mode ------------------------- //

namespace gl_compare
{
	enum	type	: GLenum_t
	{
		NONE		= GL_NONE,		// (disable)
		NEVER		= GL_NEVER,		// false
		LESS		= GL_LESS,		// <
		EQUAL		= GL_EQUAL,		// ==
		LEQUAL		= GL_LEQUAL,	// <=
		GREATER		= GL_GREATER,	// >
		NOTEQUAL	= GL_NOTEQUAL,	// !=
		GEQUAL		= GL_GEQUAL,	// >=
		ALWAYS		= GL_ALWAYS,	// true
		_INIT		= LESS,
		_UNKNOWN	= 0,
	};
}


// ------------------------- Usage Mode -------------------------- //

namespace gl_usage
{
	enum	type	: GLenum_t
	{
		STREAM_DRAW		= GL_STREAM_DRAW,
		STREAM_READ		= GL_STREAM_READ,
		STREAM_COPY		= GL_STREAM_COPY,
		STATIC_DRAW		= GL_STATIC_DRAW,
		STATIC_READ		= GL_STATIC_READ,
		STATIC_COPY		= GL_STATIC_COPY,
		DYNAMIC_DRAW	= GL_DYNAMIC_DRAW,
		DYNAMIC_READ	= GL_DYNAMIC_READ,
		DYNAMIC_COPY	= GL_DYNAMIC_COPY,
		_UNKNOWN		= 0,

		// rename
		STREAM			= STREAM_DRAW,
		STATIC			= STATIC_DRAW,
		DYNAMIC			= DYNAMIC_DRAW,
	};
}


// ----------------------- Front Face ---------------------------- //

namespace gl_front_face
{
	enum	type	: GLenum_t
	{
		CW		= GL_CW,
		CCW		= GL_CCW,
		_INIT	= CCW,
	};
}


// -------------------------- Face ------------------------------- //

namespace gl_face
{
	enum	type	: GLenum_t
	{
		FRONT				= GL_FRONT,
		BACK				= GL_BACK,
		FRONT_AND_BACK		= GL_FRONT_AND_BACK,
		_INIT				= BACK,
	};
}


// ------------------ Enable / Disable Flags --------------------- //

namespace gl_state
{
	enum	type	: GLenum_t
	{
		BLEND						= GL_BLEND,
		CLIP_DISTANCE0				= GL_CLIP_DISTANCE0,
		CLIP_DISTANCE1				= GL_CLIP_DISTANCE1,
		CLIP_DISTANCE2				= GL_CLIP_DISTANCE2,
		CLIP_DISTANCE3				= GL_CLIP_DISTANCE3,
		CLIP_DISTANCE4				= GL_CLIP_DISTANCE4,
		CLIP_DISTANCE5				= GL_CLIP_DISTANCE5,
		CLIP_DISTANCE6				= GL_CLIP_DISTANCE6,
		CLIP_DISTANCE7				= GL_CLIP_DISTANCE7,
		COLOR_LOGIC_OP				= GL_COLOR_LOGIC_OP,
		CULL_FACE					= GL_CULL_FACE,
		DEPTH_CLAMP					= GL_DEPTH_CLAMP,
		DEPTH_TEST					= GL_DEPTH_TEST,
		DITHER						= GL_DITHER,
		FRAMEBUFFER_SRGB			= GL_FRAMEBUFFER_SRGB,
		LINE_SMOOTH					= GL_LINE_SMOOTH,
		MULTISAMPLE					= GL_MULTISAMPLE,
		POLYGON_OFFSET_FILL			= GL_POLYGON_OFFSET_FILL,
		POLYGON_OFFSET_LINE			= GL_POLYGON_OFFSET_LINE,
		POLYGON_OFFSET_POINT		= GL_POLYGON_OFFSET_POINT,
		POLYGON_SMOOTH				= GL_POLYGON_SMOOTH,
		PRIMITIVE_RESTART			= GL_PRIMITIVE_RESTART,
		SAMPLE_ALPHA_TO_COVERAGE	= GL_SAMPLE_ALPHA_TO_COVERAGE,
		SAMPLE_ALPHA_TO_ONE			= GL_SAMPLE_ALPHA_TO_ONE,
		SAMPLE_COVERAGE				= GL_SAMPLE_COVERAGE,
		SAMPLE_SHADING				= GL_SAMPLE_SHADING,
		SAMPLE_MASK					= GL_SAMPLE_MASK,
		SCISSOR_TEST				= GL_SCISSOR_TEST,
		STENCIL_TEST				= GL_STENCIL_TEST,
		TEXTURE_CUBE_MAP_SEAMLESS	= GL_TEXTURE_CUBE_MAP_SEAMLESS,
		PROGRAM_POINT_SIZE			= GL_PROGRAM_POINT_SIZE,
		RASTERIZER_DISCARD			= GL_RASTERIZER_DISCARD,
		_INIT						= 0,
	};
}


// ------------------------ Vertex Type -------------------------- //

namespace gl_vertex
{
	enum	type	: GLenum_t
	{
		BYTE						= GL_BYTE,
		UBYTE						= GL_UNSIGNED_BYTE,
		SHORT						= GL_SHORT,
		USHORT						= GL_UNSIGNED_SHORT,
		INT							= GL_INT,
		UINT						= GL_UNSIGNED_INT,
		HALF						= GL_HALF_FLOAT,
		FLOAT						= GL_FLOAT,
		DOUBLE						= GL_DOUBLE,
		FIXED						= GL_FIXED,	// OES_fixed_point extension
		INT_2_10_10_10_REV			= GL_INT_2_10_10_10_REV,
		UNSIGNED_INT_2_10_10_10_REV	= GL_UNSIGNED_INT_2_10_10_10_REV,

		// for extension GL_ARB_vertex_attrib_64bit
		RGB32I						= GL_RGB32I,
		DOUBLE_VEC2					= GL_DOUBLE_VEC2,
        DOUBLE_VEC3					= GL_DOUBLE_VEC3,
        DOUBLE_VEC4					= GL_DOUBLE_VEC4,
        DOUBLE_MAT2					= GL_DOUBLE_MAT2,
        DOUBLE_MAT3					= GL_DOUBLE_MAT3,
        DOUBLE_MAT4					= GL_DOUBLE_MAT4,
        DOUBLE_MAT2x3				= GL_DOUBLE_MAT2x3,
        DOUBLE_MAT2x4				= GL_DOUBLE_MAT2x4,
        DOUBLE_MAT3x2				= GL_DOUBLE_MAT3x2,
        DOUBLE_MAT3x4				= GL_DOUBLE_MAT3x4,
        DOUBLE_MAT4x2				= GL_DOUBLE_MAT4x2,
        DOUBLE_MAT4x3				= GL_DOUBLE_MAT4x3,
		_INIT						= FLOAT,
	};
}


// ------------------------- Index Type -------------------------- //

namespace gl_index
{
	enum	type	: GLenum_t
	{
		UBYTE			= GL_UNSIGNED_BYTE,
		USHORT			= GL_UNSIGNED_SHORT,
		UINT			= GL_UNSIGNED_INT,

		UINT_8			= UBYTE,
		UINT_16			= USHORT,
		UINT_32			= UINT,
		
		_INIT			= UINT,
		_UNKNOWN		= 0,
	};
}


// ------------------------- FBO Attach -------------------------- //

namespace gl_fbo_attach
{
	enum	type	: GLenum_t
	{
		NONE			= GL_NONE,
		DEPTH			= GL_DEPTH_ATTACHMENT,
		STENCIL			= GL_STENCIL_ATTACHMENT,
		DEPTH_STENCIL	= GL_DEPTH_STENCIL_ATTACHMENT,
		COLOR_0			= GL_COLOR_ATTACHMENT0,
		COLOR_1			= GL_COLOR_ATTACHMENT1,
		COLOR_2			= GL_COLOR_ATTACHMENT2,
		COLOR_3			= GL_COLOR_ATTACHMENT3,
		COLOR_4			= GL_COLOR_ATTACHMENT4,
		COLOR_5			= GL_COLOR_ATTACHMENT5,
		COLOR_6			= GL_COLOR_ATTACHMENT6,
		COLOR_7			= GL_COLOR_ATTACHMENT7,
		COLOR_8			= GL_COLOR_ATTACHMENT8,
		COLOR_9			= GL_COLOR_ATTACHMENT9,
		COLOR_10		= GL_COLOR_ATTACHMENT10,
		COLOR_11		= GL_COLOR_ATTACHMENT11,
		COLOR_12		= GL_COLOR_ATTACHMENT12,
		COLOR_13		= GL_COLOR_ATTACHMENT13,
		COLOR_14		= GL_COLOR_ATTACHMENT14,
		COLOR_15		= GL_COLOR_ATTACHMENT15,
		_COLOR_FIRST	= COLOR_0,
		_COLOR_LAST		= COLOR_15,
		_INIT			= 0,
	};
	UX_ENUM_ADD_OPERATIONS( type );
}


// --------------------------- Logic Op -------------------------- //

namespace gl_logic_op
{
	enum	type	: GLenum_t
	{
		CLEAR				= GL_CLEAR,
		SET					= GL_SET,
		COPY				= GL_COPY,
		COPY_INVERTED		= GL_COPY_INVERTED,
		NOOP				= GL_NOOP,
		INVERT				= GL_INVERT,
		AND					= GL_AND,
		NAND				= GL_NAND,
		OR					= GL_OR,
		NOR					= GL_NOR,
		XOR					= GL_XOR,
		EQUIV				= GL_EQUIV,
		AND_REVERSE			= GL_AND_REVERSE,
		AND_INVERTED		= GL_AND_INVERTED,
		OR_REVERSE			= GL_OR_REVERSE,
		OR_INVERTED			= GL_OR_INVERTED,
		_INIT				= COPY,
	};
}


// ------------------------- Uniform Type ------------------------ //

namespace gl_uniform
{
	enum	type	: GLenum_t
	{
		_UNKNOWN				= 0,

		// Bool //
		BOOL					= GL_BOOL,
		BOOL_VEC2				= GL_BOOL_VEC2,
		BOOL_VEC3				= GL_BOOL_VEC3,
		BOOL_VEC4				= GL_BOOL_VEC4,
		
		// Float //
		FLOAT					= GL_FLOAT,
		FLOAT_VEC2				= GL_FLOAT_VEC2,
		FLOAT_VEC3				= GL_FLOAT_VEC3,
		FLOAT_VEC4				= GL_FLOAT_VEC4,
		FLOAT_MAT2				= GL_FLOAT_MAT2,
		FLOAT_MAT3				= GL_FLOAT_MAT3,
		FLOAT_MAT4				= GL_FLOAT_MAT4,
		FLOAT_MAT2x3			= GL_FLOAT_MAT2x3,
		FLOAT_MAT2x4			= GL_FLOAT_MAT2x4,
		FLOAT_MAT3x2			= GL_FLOAT_MAT3x2,
		FLOAT_MAT3x4			= GL_FLOAT_MAT3x4,
		FLOAT_MAT4x2			= GL_FLOAT_MAT4x2,
		FLOAT_MAT4x3			= GL_FLOAT_MAT4x3,

		// Double //
		DOUBLE					= GL_DOUBLE,
		DOUBLE_VEC2				= GL_DOUBLE_VEC2,
		DOUBLE_VEC3				= GL_DOUBLE_VEC3,
		DOUBLE_VEC4				= GL_DOUBLE_VEC4,
		DOUBLE_MAT2				= GL_DOUBLE_MAT2,
		DOUBLE_MAT3				= GL_DOUBLE_MAT3,
		DOUBLE_MAT4				= GL_DOUBLE_MAT4,
		DOUBLE_MAT2x3			= GL_DOUBLE_MAT2x3,
		DOUBLE_MAT2x4			= GL_DOUBLE_MAT2x4,
		DOUBLE_MAT3x2			= GL_DOUBLE_MAT3x2,
		DOUBLE_MAT3x4			= GL_DOUBLE_MAT3x4,
		DOUBLE_MAT4x2			= GL_DOUBLE_MAT4x2,
		DOUBLE_MAT4x3			= GL_DOUBLE_MAT4x3,

		// Int //
		INT						= GL_INT,
		INT_VEC2				= GL_INT_VEC2,
		INT_VEC3				= GL_INT_VEC3,
		INT_VEC4				= GL_INT_VEC4,

		// UInt //
		UINT					= GL_UNSIGNED_INT,
		UINT_VEC2				= GL_UNSIGNED_INT_VEC2,
		UINT_VEC3				= GL_UNSIGNED_INT_VEC3,
		UINT_VEC4				= GL_UNSIGNED_INT_VEC4,


		// Samplers //
		SAMPLER_1D						= GL_SAMPLER_1D,
		SAMPLER_2D						= GL_SAMPLER_2D,
		SAMPLER_3D						= GL_SAMPLER_3D,
		SAMPLER_CUBE_MAP				= GL_SAMPLER_CUBE,
		SAMPLER_1D_SHADOW				= GL_SAMPLER_1D_SHADOW,
		SAMPLER_2D_SHADOW				= GL_SAMPLER_2D_SHADOW,
		SAMPLER_2D_MS					= GL_SAMPLER_2D_MULTISAMPLE,
		SAMPLER_2D_MS_ARRAY				= GL_SAMPLER_2D_MULTISAMPLE_ARRAY,
		SAMPLER_CUBE_MAP_ARRAY			= GL_SAMPLER_CUBE_MAP_ARRAY_ARB,
		SAMPLER_CUBE_MAP_ARRAY_SHADOW	= GL_SAMPLER_CUBE_MAP_ARRAY_SHADOW_ARB,
		SAMPLER_1D_ARRAY				= GL_SAMPLER_1D_ARRAY,
		SAMPLER_2D_ARRAY				= GL_SAMPLER_2D_ARRAY,
		SAMPLER_1D_ARRAY_SHADOW			= GL_SAMPLER_1D_ARRAY_SHADOW,
		SAMPLER_2D_ARRAY_SHADOW			= GL_SAMPLER_2D_ARRAY_SHADOW,
		SAMPLER_CUBE_MAP_SHADOW			= GL_SAMPLER_CUBE_SHADOW,
		SAMPLER_BUFFER					= GL_SAMPLER_BUFFER,
		SAMPLER_2D_RECT					= GL_SAMPLER_2D_RECT,
		SAMPLER_2D_RECT_SHADOW			= GL_SAMPLER_2D_RECT_SHADOW,
		INT_SAMPLER_1D					= GL_INT_SAMPLER_1D,
		INT_SAMPLER_2D					= GL_INT_SAMPLER_2D,
		INT_SAMPLER_3D					= GL_INT_SAMPLER_3D,
		INT_SAMPLER_CUBE_MAP			= GL_INT_SAMPLER_CUBE,
		INT_SAMPLER_1D_ARRAY			= GL_INT_SAMPLER_1D_ARRAY,
		INT_SAMPLER_2D_ARRAY			= GL_INT_SAMPLER_2D_ARRAY,
		INT_SAMPLER_BUFFER				= GL_INT_SAMPLER_BUFFER,
		INT_SAMPLER_2D_RECT				= GL_INT_SAMPLER_2D_RECT,
		INT_SAMPLER_CUBE_MAP_ARRAY		= GL_INT_SAMPLER_CUBE_MAP_ARRAY_ARB,
		INT_SAMPLER_2D_MS				= GL_INT_SAMPLER_2D_MULTISAMPLE,
		INT_SAMPLER_2D_MS_ARRAY			= GL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY,
		UINT_SAMPLER_1D					= GL_UNSIGNED_INT_SAMPLER_1D,
		UINT_SAMPLER_2D					= GL_UNSIGNED_INT_SAMPLER_2D,
		UINT_SAMPLER_3D					= GL_UNSIGNED_INT_SAMPLER_3D,
		UINT_SAMPLER_CUBE_MAP			= GL_UNSIGNED_INT_SAMPLER_CUBE,
		UINT_SAMPLER_1D_ARRAY			= GL_UNSIGNED_INT_SAMPLER_1D_ARRAY,
		UINT_SAMPLER_2D_ARRAY			= GL_UNSIGNED_INT_SAMPLER_2D_ARRAY,
		UINT_SAMPLER_BUFFER				= GL_UNSIGNED_INT_SAMPLER_BUFFER,
		UINT_SAMPLER_2D_RECT			= GL_UNSIGNED_INT_SAMPLER_2D_RECT,
		UINT_SAMPLER_CUBE_MAP_ARRAY		= GL_UNSIGNED_INT_SAMPLER_CUBE_MAP_ARRAY_ARB,
		UINT_SAMPLER_2D_MS				= GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE,
		UINT_SAMPLER_2D_MS_ARRAY		= GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY,

		// Images //
		IMAGE_1D					= GL_IMAGE_1D,
		IMAGE_2D					= GL_IMAGE_2D,
		IMAGE_3D					= GL_IMAGE_3D,
		IMAGE_2D_RECT				= GL_IMAGE_2D_RECT,
		IMAGE_CUBE					= GL_IMAGE_CUBE,
		IMAGE_BUFFER				= GL_IMAGE_BUFFER,
		IMAGE_1D_ARRAY				= GL_IMAGE_1D_ARRAY,
		IMAGE_2D_ARRAY				= GL_IMAGE_2D_ARRAY,
		IMAGE_CUBE_MAP_ARRAY		= GL_IMAGE_CUBE_MAP_ARRAY,
		IMAGE_2D_MS					= GL_IMAGE_2D_MULTISAMPLE,
		IMAGE_2D_MS_ARRAY			= GL_IMAGE_2D_MULTISAMPLE_ARRAY,
		INT_IMAGE_1D				= GL_INT_IMAGE_1D,
		INT_IMAGE_2D				= GL_INT_IMAGE_2D,
		INT_IMAGE_3D				= GL_INT_IMAGE_3D,
		INT_IMAGE_2D_RECT			= GL_INT_IMAGE_2D_RECT,
		INT_IMAGE_CUBE				= GL_INT_IMAGE_CUBE,
		INT_IMAGE_BUFFER			= GL_INT_IMAGE_BUFFER,
		INT_IMAGE_1D_ARRAY			= GL_INT_IMAGE_1D_ARRAY,
		INT_IMAGE_2D_ARRAY			= GL_INT_IMAGE_2D_ARRAY,
		INT_IMAGE_CUBE_MAP_ARRAY	= GL_INT_IMAGE_CUBE_MAP_ARRAY,
		INT_IMAGE_2D_MS				= GL_INT_IMAGE_2D_MULTISAMPLE,
		INT_IMAGE_2D_MS_ARRAY		= GL_INT_IMAGE_2D_MULTISAMPLE_ARRAY,
		UINT_IMAGE_1D				= GL_UNSIGNED_INT_IMAGE_1D,
		UINT_IMAGE_2D				= GL_UNSIGNED_INT_IMAGE_2D,
		UINT_IMAGE_3D				= GL_UNSIGNED_INT_IMAGE_3D,
		UINT_IMAGE_2D_RECT			= GL_UNSIGNED_INT_IMAGE_2D_RECT,
		UINT_IMAGE_CUBE				= GL_UNSIGNED_INT_IMAGE_CUBE,
		UINT_IMAGE_BUFFER			= GL_UNSIGNED_INT_IMAGE_BUFFER,
		UINT_IMAGE_1D_ARRAY			= GL_UNSIGNED_INT_IMAGE_1D_ARRAY,
		UINT_IMAGE_2D_ARRAY			= GL_UNSIGNED_INT_IMAGE_2D_ARRAY,
		UINT_IMAGE_CUBE_MAP_ARRAY	= GL_UNSIGNED_INT_IMAGE_CUBE_MAP_ARRAY,
		UINT_IMAGE_2D_MS			= GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE,
		UINT_IMAGE_2D_MS_ARRAY		= GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE_ARRAY,
	};
}


// ------------------------ Map Buffer Flags --------------------- //

namespace gl_map_buffer
{
	enum	type	: uint16
	{
		READ				= GL_MAP_READ_BIT,
		WRITE				= GL_MAP_WRITE_BIT,

		// for MapBufferRange only //
		INVALIDATE_RANGE	= GL_MAP_INVALIDATE_RANGE_BIT,
		INVALIDATE_BUFFER	= GL_MAP_INVALIDATE_BUFFER_BIT,
		FLUSH_EXPLICIT		= GL_MAP_FLUSH_EXPLICIT_BIT,
		UNSYNCHRONIZED		= GL_MAP_UNSYNCHRONIZED_BIT,

		_INIT				= READ,
		_UNKNOWN			= 0,
	};

	UX_ENUM_BIT_OPERATIONS( type )
}


// ------------------------- Attrib Mask ------------------------- //

namespace gl_attrib_mask
{
	enum	type	: uint32
	{
		DEPTH		= GL_DEPTH_BUFFER_BIT,
		STENCIL		= GL_STENCIL_BUFFER_BIT,
		COLOR		= GL_COLOR_BUFFER_BIT,
		ALL			= 0xFFFFFFFF,
		_INIT		= COLOR,
		_UNKNOWN	= 0,
	};

	UX_ENUM_BIT_OPERATIONS( type )
}


// ------------------------ Stencil Op --------------------------- //

namespace gl_stencil_op
{
	enum	type	: GLenum_t
	{
		KEEP		= GL_KEEP,
		ZERO		= GL_ZERO,
		REPLACE		= GL_REPLACE,
		INCR		= GL_INCR,
		INCR_WRAP	= GL_INCR_WRAP,
		DECR		= GL_DECR,
		DECR_WRAP	= GL_DECR_WRAP,
		INVERT		= GL_INVERT,
		_INIT		= KEEP,
		_UNKNOWN	= 0,
	};
}


// ----------------------- Memory Barrier ------------------------ //

namespace gl_memory_barrier
{
	enum	type	: uint32
	{
		VERTEX_ATTRIB_ARRAY	= GL_VERTEX_ATTRIB_ARRAY_BARRIER_BIT,
		ELEMENT_ARRAY		= GL_ELEMENT_ARRAY_BARRIER_BIT,
		UNIFORM				= GL_UNIFORM_BARRIER_BIT,
		TEXTURE_FETCH		= GL_TEXTURE_FETCH_BARRIER_BIT,
		SHADER_IMAGE_ACCESS	= GL_SHADER_IMAGE_ACCESS_BARRIER_BIT,
		COMMAND				= GL_COMMAND_BARRIER_BIT,
		PIXEL_BUFFER		= GL_PIXEL_BUFFER_BARRIER_BIT,
		TEXTURE_UPDATE		= GL_TEXTURE_UPDATE_BARRIER_BIT,
		BUFFER_UPDATE		= GL_BUFFER_UPDATE_BARRIER_BIT,
		FRAMEBUFFER			= GL_FRAMEBUFFER_BARRIER_BIT,
		TRANSFORM_FEEDBACK	= GL_TRANSFORM_FEEDBACK_BARRIER_BIT,
		ATOMIC_COUNTER		= GL_ATOMIC_COUNTER_BARRIER_BIT,
		SHADER_STORAGE		= GL_SHADER_STORAGE_BARRIER_BIT,
		ALL					= (uint32)GL_ALL_BARRIER_BITS,
		_INIT				= 0,
		_UNKNOWN			= 0,
	};

	UX_ENUM_BIT_OPERATIONS( type )
}


// ------------------------ Polygon Mode ------------------------- //

namespace gl_polygon_mode
{
	enum	type :	GLenum_t
	{
		POINT	= GL_POINT,
		LINE	= GL_LINE,
		FILL	= GL_FILL,
	};
}


// ------------------------- Access Type ------------------------- //

namespace gl_access
{
	enum	type :	GLenum_t
	{
		READ		= GL_READ_ONLY,
		WRITE		= GL_WRITE_ONLY,
		READ_WRITE	= GL_READ_WRITE,
	};
}


// -------------------- Internal Image Format -------------------- //

namespace gl_image_fmt
{
	enum	type :	GLenum_t
	{
		// float
		RGBA32F			= GL_RGBA32F,
		RGBA16F			= GL_RGBA16F,
		RG32F			= GL_RG32F,
		RG16F			= GL_RG16F,
		R32F			= GL_R32F,
		R16F			= GL_R16F,
		R11F_G11F_B10F	= GL_R11F_G11F_B10F,
		// unsigned integer
		RGBA32UI		= GL_RGBA32UI,
		RGBA16UI		= GL_RGBA16UI,
		RGB10_A2UI		= GL_RGB10_A2UI,
		RGBA8UI			= GL_RGBA8UI,
		RG32UI			= GL_RG32UI,
		RG16UI			= GL_RG16UI,
		RG8UI			= GL_RG8UI,
		R32UI			= GL_R32UI,
		R16UI			= GL_R16UI,
		R8UI			= GL_R8UI,
		// integer
		RGBA32I			= GL_RGBA32I,
		RGBA16I			= GL_RGBA16I,
		RGBA8I			= GL_RGBA8I,
		RG32I			= GL_RG32I,
		RG16I			= GL_RG16I,
		RG8I			= GL_RG8I,
		R32I			= GL_R32I,
		R16I			= GL_R16I,
		R8I				= GL_R8I,
		// unsigned normalized
		RGBA16			= GL_RGBA16,
		RGB10_A2		= GL_RGB10_A2,
		RGBA8			= GL_RGBA8,
		RG16			= GL_RG16,
		RG8				= GL_RG8,
		R16				= GL_R16,
		R8				= GL_R8,
		// signed normalized
		RGBA16_SNORM	= GL_RGBA16_SNORM,
		RGBA8_SNORM		= GL_RGBA8_SNORM,
		RG16_SNORM		= GL_RG16_SNORM,
		RG8_SNORM		= GL_RG8_SNORM,
		R16_SNORM		= GL_R16_SNORM,
		R8_SNORM		= GL_R8_SNORM,

		_UNKNOWN		= 0,
	};
}


// ---------------- Texture Buffer Internal Format --------------- //

namespace gl_tbo_iformat
{
	enum	type :	GLenum_t
	{
		_UNKNOWN					= 0,

		// unsigned normalized
		R8							= GL_R8,
		R16							= GL_R16,
		RG8							= GL_RG8,
		RG16						= GL_RG16,
		RGB8						= GL_RGB8,
		RGB16						= GL_RGB16,
		RGBA8						= GL_RGBA8,
		RGBA16						= GL_RGBA16,
		// float
		RGBA32F						= GL_RGBA32F,
		RGBA16F						= GL_RGBA16F,
		RGB32F						= GL_RGB32F,
		RGB16F						= GL_RGB16F,
		RG32F						= GL_RG32F,
		RG16F						= GL_RG16F,
		R32F						= GL_R32F,
		R16F						= GL_R16F,
		// integer
		RGBA32I						= GL_RGBA32I,
		RGBA16I						= GL_RGBA16I,
		RGBA8I						= GL_RGBA8I,
		RGB32I						= GL_RGB32I,
		RGB16I						= GL_RGB16I,
		RGB8I						= GL_RGB8I,
		RG32I						= GL_RG32I,
		RG16I						= GL_RG16I,
		RG8I						= GL_RG8I,
		R32I						= GL_R32I,
		R16I						= GL_R16I,
		R8I							= GL_R8I,
		// unsigned integer
		RGBA32UI					= GL_RGBA32UI,
		RGBA16UI					= GL_RGBA16UI,
		RGBA8UI						= GL_RGBA8UI,
		RGB32UI						= GL_RGB32UI,
		RGB16UI						= GL_RGB16UI,
		RGB8UI						= GL_RGB8UI,
		RG32UI						= GL_RG32UI,
		RG16UI						= GL_RG16UI,
		RG8UI						= GL_RG8UI,
		R32UI						= GL_R32UI,
		R16UI						= GL_R16UI,
		R8UI						= GL_R8UI,
	};
}


// ------------------- Texture Internal Format ------------------- //

namespace gl_tex_iformat
{
	using namespace gl_tbo_iformat;

	// depth & stencil
	const type	DEPTH16					= (type)GL_DEPTH_COMPONENT16;
	const type	DEPTH24					= (type)GL_DEPTH_COMPONENT24;
	const type	DEPTH32					= (type)GL_DEPTH_COMPONENT32;
	const type	DEPTH32F				= (type)GL_DEPTH_COMPONENT32F;
	const type	DEPTH24_STENCIL8		= (type)GL_DEPTH24_STENCIL8;
	const type	DEPTH32F_STENCIL8		= (type)GL_DEPTH32F_STENCIL8;
	// unsigned normalized
	const type	R3_G3_B2				= (type)GL_R3_G3_B2;
	const type	RGB4					= (type)GL_RGB4;
	const type	RGB5					= (type)GL_RGB5;
	const type	RGB10					= (type)GL_RGB10;
	const type	RGB12					= (type)GL_RGB12;
	const type	RGBA2					= (type)GL_RGBA2;
	const type	RGBA4					= (type)GL_RGBA4;
	const type	RGB5_A1					= (type)GL_RGB5_A1;
	const type	RGB10_A2				= (type)GL_RGB10_A2;
	const type	RGBA12					= (type)GL_RGBA12;
	const type	SRGB8					= (type)GL_SRGB8;
	const type	SRGBA8					= (type)GL_SRGB8_ALPHA8;
	// signed normalized
	const type	R8_SNORM				= (type)GL_R8_SNORM;
	const type	R16_SNORM				= (type)GL_R16_SNORM;
	const type	RG8_SNORM				= (type)GL_RG8_SNORM;
	const type	RG16_SNORM				= (type)GL_RG16_SNORM;
	const type	RGB8_SNORM				= (type)GL_RGB8_SNORM;
	const type	RGB16_SNORM				= (type)GL_RGB16_SNORM;
	const type	RGBA8_SNORM				= (type)GL_RGBA8_SNORM;
	const type	RGBA16_SNORM			= (type)GL_RGBA16_SNORM;
	// float
	const type	R11F_G11F_B10F			= (type)GL_R11F_G11F_B10F;
	const type	RGB9_E5					= (type)GL_RGB9_E5;
	// unsigned integer
	const type	RGB10_A2UI				= (type)GL_RGB10_A2UI;
	// compressed formats
	const type	COMPRESSED_RED			= (type)GL_COMPRESSED_RED;
	const type	COMPRESSED_RG			= (type)GL_COMPRESSED_RG;
	const type	COMPRESSED_RGB			= (type)GL_COMPRESSED_RGB;
	const type	COMPRESSED_RGBA			= (type)GL_COMPRESSED_RGBA;
	const type	COMPRESSED_SRGB			= (type)GL_COMPRESSED_SRGB;
	const type	COMPRESSED_SRGBA		= (type)GL_COMPRESSED_SRGB_ALPHA;
	const type	DXT1_RGB8				= (type)GL_COMPRESSED_RGB_S3TC_DXT1_EXT;
	const type	DXT1_RGB8_A1			= (type)GL_COMPRESSED_RGBA_S3TC_DXT1_EXT;
	const type	DXT3_RGBA8				= (type)GL_COMPRESSED_RGBA_S3TC_DXT3_EXT;
	const type	DXT5_RGBA8				= (type)GL_COMPRESSED_RGBA_S3TC_DXT5_EXT;
	const type	RGTC1_RED8				= (type)GL_COMPRESSED_RED_RGTC1;
	const type	RGTC1_RED8_SNORM		= (type)GL_COMPRESSED_SIGNED_RED_RGTC1;
	const type	RGTC2_RG8				= (type)GL_COMPRESSED_RG_RGTC2;
	const type	RGTC2_RG8_SNORM			= (type)GL_COMPRESSED_SIGNED_RG_RGTC2;
	const type	BPTC_RGBA8				= (type)GL_COMPRESSED_RGBA_BPTC_UNORM_ARB;
	const type	BPTC_SRGBA8				= (type)GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM_ARB;
	const type	BPTC_RGB16F_SIGNED		= (type)GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT_ARB;
	const type	BPTC_RGB16F_UNSIGNED	= (type)GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_ARB;
	const type	ETC2_RGB8				= (type)GL_COMPRESSED_RGB8_ETC2;
	const type	ECT2_SRGB8				= (type)GL_COMPRESSED_SRGB8_ETC2;
	const type	ETC2_RGB8_A1			= (type)GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2;
	const type	ETC2_SRGB8_A1			= (type)GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2;
	const type	ETC2_RGBA8				= (type)GL_COMPRESSED_RGBA8_ETC2_EAC;
	const type	ETC2_SRGB8_A8			= (type)GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC;
	const type	EAC_R11					= (type)GL_COMPRESSED_R11_EAC;
	const type	EAC_R11_SIGNED			= (type)GL_COMPRESSED_SIGNED_R11_EAC;
	const type	EAC_RG11				= (type)GL_COMPRESSED_RG11_EAC;
	const type	EAC_RG11_SIGNED			= (type)GL_COMPRESSED_SIGNED_RG11_EAC;
}


// --------------------- Render Target Format -------------------- //

namespace gl_rt_format
{
	using namespace gl_tbo_iformat;
	
	// unsigned normalized
	const type	SRGB8					= (type)GL_SRGB8;
	const type	SRGBA8					= (type)GL_SRGB8_ALPHA8;
	// unsigned integer
	const type	RGB10_A2UI				= (type)GL_RGB10_A2UI;
	// float
	const type	R11F_G11F_B10F			= (type)GL_R11F_G11F_B10F;
	// depth & stencil
	const type	DEPTH16					= (type)GL_DEPTH_COMPONENT16;
	const type	DEPTH24					= (type)GL_DEPTH_COMPONENT24;
	const type	DEPTH32					= (type)GL_DEPTH_COMPONENT32;
	const type	DEPTH32F				= (type)GL_DEPTH_COMPONENT32F;
	const type	DEPTH24_STENCIL8		= (type)GL_DEPTH24_STENCIL8;
	const type	DEPTH32F_STENCIL8		= (type)GL_DEPTH32F_STENCIL8;
	const type	STENCIL1				= (type)GL_STENCIL_INDEX1;
	const type	STENCIL4				= (type)GL_STENCIL_INDEX4;
	const type	STENCIL8				= (type)GL_STENCIL_INDEX8;
	const type	STENCIL16				= (type)GL_STENCIL_INDEX16;
}


// ------------------------- Pixel Format ------------------------ //

namespace gl_pixel_format
{
	enum	type :	GLenum_t
	{
		_UNKNOWN					= 0,
		RED							= GL_RED,
		RED_INTEGER					= GL_RED_INTEGER,
		R							= GL_RED,
		R_INTEGER					= GL_RED_INTEGER,
		RG							= GL_RG,
		RG_INTEGER					= GL_RG_INTEGER,
		RGB							= GL_RGB,
		RGB_INTEGER					= GL_RGB_INTEGER,
		BGR							= GL_BGR,
		BGR_INTEGER					= GL_BGR_INTEGER,
		RGBA						= GL_RGBA,
		RGBA_INTEGER				= GL_RGBA_INTEGER,
		BGRA						= GL_BGRA,
		BGRA_INTEGER				= GL_BGRA_INTEGER,
		DEPTH						= GL_DEPTH_COMPONENT,
		DEPTH_STENCIL				= GL_DEPTH_STENCIL,
		STENCIL						= GL_STENCIL_INDEX,
	};
}


// ------------------------- Pixel Type -------------------------- //

namespace gl_pixel
{
	enum	type :	GLenum_t
	{
		_UNKNOWN				= 0,
		UBYTE					= GL_UNSIGNED_BYTE,
		BYTE					= GL_BYTE,
		USHORT					= GL_UNSIGNED_SHORT,
		SHORT					= GL_SHORT,
		UINT					= GL_UNSIGNED_INT,
		INT						= GL_INT,
		HALF					= GL_HALF_FLOAT,
		//FIXED					= GL_FIXED,
		FLOAT					= GL_FLOAT,
		//DOUBLE					= GL_DOUBLE,
		UBYTE_3_3_2				= GL_UNSIGNED_BYTE_3_3_2,
		UBYTE_2_3_3_REV			= GL_UNSIGNED_BYTE_2_3_3_REV,
		USHORT_5_6_5			= GL_UNSIGNED_SHORT_5_6_5,
		USHORT_5_6_5_REV		= GL_UNSIGNED_SHORT_5_6_5_REV,
		USHORT_4_4_4_4			= GL_UNSIGNED_SHORT_4_4_4_4,
		USHORT_4_4_4_4_REV		= GL_UNSIGNED_SHORT_4_4_4_4_REV,
		USHORT_5_5_5_1			= GL_UNSIGNED_SHORT_5_5_5_1,
		USHORT_1_5_5_5_REV		= GL_UNSIGNED_SHORT_1_5_5_5_REV,
		UINT_8_8_8_8			= GL_UNSIGNED_INT_8_8_8_8,
		UINT_8_8_8_8_REV		= GL_UNSIGNED_INT_8_8_8_8_REV,
		UINT_10_10_10_2			= GL_UNSIGNED_INT_10_10_10_2,
		UINT_2_10_10_10_REV		= GL_UNSIGNED_INT_2_10_10_10_REV,
		UINT_10F_11F_11F_REV	= GL_UNSIGNED_INT_10F_11F_11F_REV,
		UINT_5_9_9_9_REV		= GL_UNSIGNED_INT_5_9_9_9_REV,
		UINT_24_8				= GL_UNSIGNED_INT_24_8,
		FLOAT32_UINT_24_8		= GL_FLOAT_32_UNSIGNED_INT_24_8_REV,
	};
}


// ---------------------- Texture Addressing --------------------- //

namespace gl_wrap
{
	enum	type :	GLenum_t
	{
		CLAMP			= GL_CLAMP_TO_EDGE,
		MIRRORED_REPEAT	= GL_MIRRORED_REPEAT,
		REPEAT			= GL_REPEAT,
		_INIT			= REPEAT,
		_UNKNOWN		= 0,
	};
}


// ----------------------- Texture Filtering --------------------- //

namespace gl_filter
{
	enum	type :	GLenum_t
	{
		// min & mag
		NEAREST					= GL_NEAREST,
		LINEAR					= GL_LINEAR,
		// min only
		NEAREST_MIPMAP_NEAREST	= GL_NEAREST_MIPMAP_NEAREST,
		LINEAR_MIPMAP_NEAREST	= GL_LINEAR_MIPMAP_NEAREST,
		NEAREST_MIPMAP_LINEAR	= GL_NEAREST_MIPMAP_LINEAR,
		LINEAR_MIPMAP_LINEAR	= GL_LINEAR_MIPMAP_LINEAR,
	};
}


// ----------------------- Texture Swizzle ----------------------- //

namespace gl_swizzle
{
	enum	type :	GLenum_t
	{
		ZERO		= GL_ZERO,
		ONE			= GL_ONE,
		R			= GL_RED,
		G			= GL_GREEN,
		B			= GL_BLUE,
		A			= GL_ALPHA,
	};
}


// --------------------- Texture Component Type ------------------ //

namespace gl_tex_component
{
	enum type	: GLenum_t
	{
		NONE		= GL_NONE,
		SNORM		= GL_SIGNED_NORMALIZED,
		UNORM		= GL_UNSIGNED_NORMALIZED,
		FLOAT		= GL_FLOAT,
		FIXED		= GL_FIXED,
		INT			= GL_INT,
		UINT		= GL_UNSIGNED_INT,
	};
}


// ------------------------ Shader Types ------------------------- //

namespace gl_shader
{
	enum	type :	GLenum_t
	{
		VERTEX				= GL_VERTEX_SHADER,
		TESS_CONTROL		= GL_TESS_CONTROL_SHADER,
		TESS_EVALUATION		= GL_TESS_EVALUATION_SHADER,
		GEOMETRY			= GL_GEOMETRY_SHADER,
		FRAGMENT			= GL_FRAGMENT_SHADER,
		COMPUTE				= GL_COMPUTE_SHADER,
		_UNKNOWN			= 0,
	};

	enum	bits :	uint
	{
		VERTEX_BIT			= GL_VERTEX_SHADER_BIT,
		FRAGMENT_BIT		= GL_FRAGMENT_SHADER_BIT,
		GEOMETRY_BIT		= GL_GEOMETRY_SHADER_BIT,
		TESS_CONTROL_BIT	= GL_TESS_CONTROL_SHADER_BIT,
		TESS_EVALUATION_BIT	= GL_TESS_EVALUATION_SHADER_BIT,
		COMPUTE_BIT			= GL_COMPUTE_SHADER_BIT,
		ALL					= 0xFFFFFFFF,
		_UNKNOWN_BIT		= 0,
	};

	enum	index : uint
	{
		VERTEX_IDX			= 0,
		FRAGMENT_IDX,
		GEOMETRY_IDX,
		TESS_CONTROL_IDX,
		TESS_EVALUATION_IDX,
		COMPUTE_IDX,
		_IDX_COUNT,
		_IDX_FIRST	= VERTEX_IDX,
	};

	inline type BitToType(bits b)
	{
		switch ( b )
		{
			case VERTEX_BIT	:			return VERTEX;
			case TESS_CONTROL_BIT :		return TESS_CONTROL;
			case TESS_EVALUATION_BIT :	return TESS_EVALUATION;
			case GEOMETRY_BIT :			return GEOMETRY;
			case FRAGMENT_BIT :			return FRAGMENT;
			case COMPUTE_BIT :			return COMPUTE;
		};
		WARNING("Unsupported shader bit or greater then one bit are not zero");
		return _UNKNOWN;
	}

	inline bits TypeToBit(type t)
	{
		switch ( t )
		{
			case VERTEX :				return VERTEX_BIT;
			case TESS_CONTROL :			return TESS_CONTROL_BIT;
			case TESS_EVALUATION :		return TESS_EVALUATION_BIT;
			case GEOMETRY :				return GEOMETRY_BIT;
			case FRAGMENT :				return FRAGMENT_BIT;
			case COMPUTE :				return COMPUTE_BIT;
		};
		WARNING("Unknown shader type");
		return _UNKNOWN_BIT;
	}

	inline bits IndexToBits(index i)
	{
		return bits(1 << i);
	}

	inline type IndexToType(index i)
	{
		return BitToType( IndexToBits( i ) );
	}

	UX_ENUM_BIT_OPERATIONS( bits );
	UX_ENUM_ADD_OPERATIONS( index );
}


// ---------------------- Shader Precision ----------------------- //

namespace gl_shader_precision
{
	enum	type :	GLenum_t
	{
		LOW_FLOAT		= GL_LOW_FLOAT,
        MEDIUM_FLOAT	= GL_MEDIUM_FLOAT,
        HIGH_FLOAT		= GL_HIGH_FLOAT,
        LOW_INT			= GL_LOW_INT,
        MEDIUM_INT		= GL_MEDIUM_INT,
        HIGH_INT		= GL_HIGH_INT,
	};
}


// ----------------------- Color Encoding ------------------------ //

namespace gl_color_encoding
{
	enum	type :	GLenum_t
	{
		NONE	= GL_NONE,
		LINEAR	= GL_LINEAR,
		SRGB	= GL_SRGB,
	};
}



// ------------------------ Support Type ------------------------- //

namespace gl_support
{
	enum	type :	GLenum_t
	{
		FULL_SUPPORT		= GL_FULL_SUPPORT,
		CAVEAT_SUPPORT		= GL_CAVEAT_SUPPORT,
		NONE				= GL_NONE,
	};
}


// ------------------------ Image Class -------------------------- //

namespace gl_image_class
{
	enum	type :	GLenum_t
	{
		IC_4x32			= GL_IMAGE_CLASS_4_X_32,
		IC_2x32			= GL_IMAGE_CLASS_2_X_32,
		IC_1x32			= GL_IMAGE_CLASS_1_X_32,
		IC_4x16			= GL_IMAGE_CLASS_4_X_16,
		IC_2x16			= GL_IMAGE_CLASS_2_X_16,
		IC_1x16			= GL_IMAGE_CLASS_1_X_16,
		IC_4x8			= GL_IMAGE_CLASS_4_X_8,
		IC_2x8			= GL_IMAGE_CLASS_2_X_8,
		IC_1x8			= GL_IMAGE_CLASS_1_X_8,
		IC_11_11_10_F	= GL_IMAGE_CLASS_11_11_10,
		IC_10_10_10_2	= GL_IMAGE_CLASS_10_10_10_2,
		NONE			= 0,
	};
}


// ---------------- Image Format Compatibility ------------------- //

namespace gl_img_fmt_compatibility
{
	enum	type :	GLenum_t
	{
		BY_SIZE		= GL_IMAGE_FORMAT_COMPATIBILITY_BY_SIZE,
		BY_CLASS	= GL_IMAGE_FORMAT_COMPATIBILITY_BY_CLASS,
		NONE		= GL_NONE,
	};
}


// -------------------- Texture View Class ----------------------- //

namespace gl_tex_view_class
{
	enum	type :	GLenum_t
	{
		VC_128_BITS			= GL_VIEW_CLASS_128_BITS,
		VC_96_BITS			= GL_VIEW_CLASS_96_BITS,
		VC_64_BITS			= GL_VIEW_CLASS_64_BITS,
		VC_48_BITS			= GL_VIEW_CLASS_48_BITS,
		VC_32_BITS			= GL_VIEW_CLASS_32_BITS,
		VC_24_BITS			= GL_VIEW_CLASS_24_BITS,
		VC_16_BITS			= GL_VIEW_CLASS_16_BITS,
		VC_8_BITS			= GL_VIEW_CLASS_8_BITS,
		VC_S3TC_DXT1_RGB	= GL_VIEW_CLASS_S3TC_DXT1_RGB,
		VC_S3TC_DXT1_RGBA	= GL_VIEW_CLASS_S3TC_DXT1_RGBA,
		VC_S3TC_DXT3_RGBA	= GL_VIEW_CLASS_S3TC_DXT3_RGBA,
		VC_S3TC_DXT5_RGBA	= GL_VIEW_CLASS_S3TC_DXT5_RGBA,
		VC_RGTC1_RED		= GL_VIEW_CLASS_RGTC1_RED,
		VC_RGTC2_RG			= GL_VIEW_CLASS_RGTC2_RG,
		VC_BPTC_UNORM		= GL_VIEW_CLASS_BPTC_UNORM,
		VC_BPTC_FLOAT		= GL_VIEW_CLASS_BPTC_FLOAT,
	};
}


// --------------- Transform Feedback Write Mode ----------------- //

namespace gl_tf_mode
{
	enum	type :	GLenum_t
	{
		INTERLEAVED		= GL_INTERLEAVED_ATTRIBS,
		SEPARATE		= GL_SEPARATE_ATTRIBS,
	};
}

}	// GLShell


// Enums Meta Data
UX_ENUM_META_OBJECT( GLShell::gl_object::type );
UX_ENUM_META_OBJECT( GLShell::gl_buffer::type );
UX_ENUM_META_OBJECT( GLShell::gl_query::type );
UX_ENUM_META_OBJECT( GLShell::gl_cond_render::type );
UX_ENUM_META_OBJECT( GLShell::gl_cube_face::type );
UX_ENUM_META_OBJECT( GLShell::gl_texture::type );
UX_ENUM_META_OBJECT( GLShell::gl_draw_buffer::type );
UX_ENUM_META_OBJECT( GLShell::gl_system_buffer::type );
UX_ENUM_META_OBJECT( GLShell::gl_read_buffer::type );
UX_ENUM_META_OBJECT( GLShell::gl_fbo_target::type );
UX_ENUM_META_OBJECT( GLShell::gl_fbo_object::type );
UX_ENUM_META_OBJECT( GLShell::gl_primitive::type );
UX_ENUM_META_OBJECT( GLShell::gl_blend_equation::type );
UX_ENUM_META_OBJECT( GLShell::gl_blend_func::type );
UX_ENUM_META_OBJECT( GLShell::gl_compare::type );
UX_ENUM_META_OBJECT( GLShell::gl_usage::type );
UX_ENUM_META_OBJECT( GLShell::gl_front_face::type );
UX_ENUM_META_OBJECT( GLShell::gl_face::type );
UX_ENUM_META_OBJECT( GLShell::gl_state::type );
UX_ENUM_META_OBJECT( GLShell::gl_vertex::type );
UX_ENUM_META_OBJECT( GLShell::gl_index::type );
UX_ENUM_META_OBJECT( GLShell::gl_fbo_attach::type );
UX_ENUM_META_OBJECT( GLShell::gl_logic_op::type );
UX_ENUM_META_OBJECT( GLShell::gl_uniform::type );
UX_ENUM_META_OBJECT( GLShell::gl_map_buffer::type );
UX_ENUM_META_OBJECT( GLShell::gl_attrib_mask::type );
UX_ENUM_META_OBJECT( GLShell::gl_stencil_op::type );
UX_ENUM_META_OBJECT( GLShell::gl_memory_barrier::type );
UX_ENUM_META_OBJECT( GLShell::gl_polygon_mode::type );
UX_ENUM_META_OBJECT( GLShell::gl_access::type );
UX_ENUM_META_OBJECT( GLShell::gl_image_fmt::type );
UX_ENUM_META_OBJECT( GLShell::gl_tex_iformat::type );
UX_ENUM_META_OBJECT( GLShell::gl_pixel_format::type );
UX_ENUM_META_OBJECT( GLShell::gl_pixel::type );
UX_ENUM_META_OBJECT( GLShell::gl_wrap::type );
UX_ENUM_META_OBJECT( GLShell::gl_filter::type );
UX_ENUM_META_OBJECT( GLShell::gl_swizzle::type );
UX_ENUM_META_OBJECT( GLShell::gl_tex_component::type );
UX_ENUM_META_OBJECT( GLShell::gl_shader::type );
UX_ENUM_META_OBJECT( GLShell::gl_shader::bits );
UX_ENUM_META_OBJECT( GLShell::gl_shader_precision::type );
UX_ENUM_META_OBJECT( GLShell::gl_color_encoding::type );
UX_ENUM_META_OBJECT( GLShell::gl_support::type );
UX_ENUM_META_OBJECT( GLShell::gl_image_class::type );
UX_ENUM_META_OBJECT( GLShell::gl_img_fmt_compatibility::type );
UX_ENUM_META_OBJECT( GLShell::gl_tex_view_class::type );
UX_ENUM_META_OBJECT( GLShell::gl_tf_mode::type );

//-------------------------------------------------------------------

}	// UX_STL

#endif	// _UXS_GL_ENUMS_H